home *** CD-ROM | disk | FTP | other *** search
/ Personal Computer World 2007 September / PCWSEP07.iso / Software / Linux / Linux Mint 3.0 Light / LinuxMint-3.0-Light.iso / casper / filesystem.squashfs / usr / src / linux-headers-2.6.20-15 / scripts / kernel-doc < prev    next >
Encoding:
Text File  |  2007-04-12  |  51.5 KB  |  1,921 lines

  1. #!/usr/bin/perl -w
  2.  
  3. use strict;
  4.  
  5. ## Copyright (c) 1998 Michael Zucchi, All Rights Reserved        ##
  6. ## Copyright (C) 2000, 1  Tim Waugh <twaugh@redhat.com>          ##
  7. ## Copyright (C) 2001  Simon Huggins                             ##
  8. ##                                  ##
  9. ## #define enhancements by Armin Kuster <akuster@mvista.com>     ##
  10. ## Copyright (c) 2000 MontaVista Software, Inc.             ##
  11. ##                                  ##
  12. ## This software falls under the GNU General Public License.     ##
  13. ## Please read the COPYING file for more information             ##
  14.  
  15. # w.o. 03-11-2000: added the '-filelist' option.
  16.  
  17. # 18/01/2001 -     Cleanups
  18. #         Functions prototyped as foo(void) same as foo()
  19. #         Stop eval'ing where we don't need to.
  20. # -- huggie@earth.li
  21.  
  22. # 27/06/2001 -  Allowed whitespace after initial "/**" and
  23. #               allowed comments before function declarations.
  24. # -- Christian Kreibich <ck@whoop.org>
  25.  
  26. # Still to do:
  27. #     - add perldoc documentation
  28. #     - Look more closely at some of the scarier bits :)
  29.  
  30. # 26/05/2001 -     Support for separate source and object trees.
  31. #        Return error code.
  32. #         Keith Owens <kaos@ocs.com.au>
  33.  
  34. # 23/09/2001 - Added support for typedefs, structs, enums and unions
  35. #              Support for Context section; can be terminated using empty line
  36. #              Small fixes (like spaces vs. \s in regex)
  37. # -- Tim Jansen <tim@tjansen.de>
  38.  
  39.  
  40. #
  41. # This will read a 'c' file and scan for embedded comments in the
  42. # style of gnome comments (+minor extensions - see below).
  43. #
  44.  
  45. # Note: This only supports 'c'.
  46.  
  47. # usage:
  48. # kernel-doc [ -docbook | -html | -text | -man ]
  49. #           [ -function funcname [ -function funcname ...] ] c file(s)s > outputfile
  50. # or
  51. #           [ -nofunction funcname [ -function funcname ...] ] c file(s)s > outputfile
  52. #
  53. #  Set output format using one of -docbook -html -text or -man.  Default is man.
  54. #
  55. #  -function funcname
  56. #    If set, then only generate documentation for the given function(s).  All
  57. #    other functions are ignored.
  58. #
  59. #  -nofunction funcname
  60. #    If set, then only generate documentation for the other function(s).
  61. #    Cannot be used together with -function
  62. #    (yes, that's a bug -- perl hackers can fix it 8))
  63. #
  64. #  c files - list of 'c' files to process
  65. #
  66. #  All output goes to stdout, with errors to stderr.
  67.  
  68. #
  69. # format of comments.
  70. # In the following table, (...)? signifies optional structure.
  71. #                         (...)* signifies 0 or more structure elements
  72. # /**
  73. #  * function_name(:)? (- short description)?
  74. # (* @parameterx: (description of parameter x)?)*
  75. # (* a blank line)?
  76. #  * (Description:)? (Description of function)?
  77. #  * (section header: (section description)? )*
  78. #  (*)?*/
  79. #
  80. # So .. the trivial example would be:
  81. #
  82. # /**
  83. #  * my_function
  84. #  **/
  85. #
  86. # If the Description: header tag is ommitted, then there must be a blank line
  87. # after the last parameter specification.
  88. # e.g.
  89. # /**
  90. #  * my_function - does my stuff
  91. #  * @my_arg: its mine damnit
  92. #  *
  93. #  * Does my stuff explained.
  94. #  */
  95. #
  96. #  or, could also use:
  97. # /**
  98. #  * my_function - does my stuff
  99. #  * @my_arg: its mine damnit
  100. #  * Description: Does my stuff explained.
  101. #  */
  102. # etc.
  103. #
  104. # Beside functions you can also write documentation for structs, unions,
  105. # enums and typedefs. Instead of the function name you must write the name
  106. # of the declaration;  the struct/union/enum/typedef must always precede
  107. # the name. Nesting of declarations is not supported.
  108. # Use the argument mechanism to document members or constants.
  109. # e.g.
  110. # /**
  111. #  * struct my_struct - short description
  112. #  * @a: first member
  113. #  * @b: second member
  114. #  *
  115. #  * Longer description
  116. #  */
  117. # struct my_struct {
  118. #     int a;
  119. #     int b;
  120. # /* private: */
  121. #     int c;
  122. # };
  123. #
  124. # All descriptions can be multiline, except the short function description.
  125. #
  126. # You can also add additional sections. When documenting kernel functions you
  127. # should document the "Context:" of the function, e.g. whether the functions
  128. # can be called form interrupts. Unlike other sections you can end it with an
  129. # empty line.
  130. # Example-sections should contain the string EXAMPLE so that they are marked
  131. # appropriately in DocBook.
  132. #
  133. # Example:
  134. # /**
  135. #  * user_function - function that can only be called in user context
  136. #  * @a: some argument
  137. #  * Context: !in_interrupt()
  138. #  *
  139. #  * Some description
  140. #  * Example:
  141. #  *    user_function(22);
  142. #  */
  143. # ...
  144. #
  145. #
  146. # All descriptive text is further processed, scanning for the following special
  147. # patterns, which are highlighted appropriately.
  148. #
  149. # 'funcname()' - function
  150. # '$ENVVAR' - environmental variable
  151. # '&struct_name' - name of a structure (up to two words including 'struct')
  152. # '@parameter' - name of a parameter
  153. # '%CONST' - name of a constant.
  154.  
  155. my $errors = 0;
  156. my $warnings = 0;
  157.  
  158. # match expressions used to find embedded type information
  159. my $type_constant = '\%([-_\w]+)';
  160. my $type_func = '(\w+)\(\)';
  161. my $type_param = '\@(\w+)';
  162. my $type_struct = '\&((struct\s*)?[_\w]+)';
  163. my $type_env = '(\$\w+)';
  164.  
  165. # Output conversion substitutions.
  166. #  One for each output format
  167.  
  168. # these work fairly well
  169. my %highlights_html = ( $type_constant, "<i>\$1</i>",
  170.             $type_func, "<b>\$1</b>",
  171.             $type_struct, "<i>\$1</i>",
  172.             $type_param, "<tt><b>\$1</b></tt>" );
  173. my $blankline_html = "<p>";
  174.  
  175. # XML, docbook format
  176. my %highlights_xml = ( "([^=])\\\"([^\\\"<]+)\\\"", "\$1<quote>\$2</quote>",
  177.             $type_constant, "<constant>\$1</constant>",
  178.             $type_func, "<function>\$1</function>",
  179.             $type_struct, "<structname>\$1</structname>",
  180.             $type_env, "<envar>\$1</envar>",
  181.             $type_param, "<parameter>\$1</parameter>" );
  182. my $blankline_xml = "</para><para>\n";
  183.  
  184. # gnome, docbook format
  185. my %highlights_gnome = ( $type_constant, "<replaceable class=\"option\">\$1</replaceable>",
  186.              $type_func, "<function>\$1</function>",
  187.              $type_struct, "<structname>\$1</structname>",
  188.              $type_env, "<envar>\$1</envar>",
  189.              $type_param, "<parameter>\$1</parameter>" );
  190. my $blankline_gnome = "</para><para>\n";
  191.  
  192. # these are pretty rough
  193. my %highlights_man = ( $type_constant, "\$1",
  194.                $type_func, "\\\\fB\$1\\\\fP",
  195.                $type_struct, "\\\\fI\$1\\\\fP",
  196.                $type_param, "\\\\fI\$1\\\\fP" );
  197. my $blankline_man = "";
  198.  
  199. # text-mode
  200. my %highlights_text = ( $type_constant, "\$1",
  201.             $type_func, "\$1",
  202.             $type_struct, "\$1",
  203.             $type_param, "\$1" );
  204. my $blankline_text = "";
  205.  
  206.  
  207. sub usage {
  208.     print "Usage: $0 [ -v ] [ -docbook | -html | -text | -man ]\n";
  209.     print "         [ -function funcname [ -function funcname ...] ]\n";
  210.     print "         [ -nofunction funcname [ -nofunction funcname ...] ]\n";
  211.     print "         c source file(s) > outputfile\n";
  212.     exit 1;
  213. }
  214.  
  215. # read arguments
  216. if ($#ARGV==-1) {
  217.     usage();
  218. }
  219.  
  220. my $verbose = 0;
  221. my $output_mode = "man";
  222. my %highlights = %highlights_man;
  223. my $blankline = $blankline_man;
  224. my $modulename = "Kernel API";
  225. my $function_only = 0;
  226. my $man_date = ('January', 'February', 'March', 'April', 'May', 'June',
  227.         'July', 'August', 'September', 'October',
  228.         'November', 'December')[(localtime)[4]] .
  229.   " " . ((localtime)[5]+1900);
  230.  
  231. # Essentially these are globals
  232. # They probably want to be tidied up made more localised or summat.
  233. # CAVEAT EMPTOR!  Some of the others I localised may not want to be which
  234. # could cause "use of undefined value" or other bugs.
  235. my ($function, %function_table,%parametertypes,$declaration_purpose);
  236. my ($type,$declaration_name,$return_type);
  237. my ($newsection,$newcontents,$prototype,$filelist, $brcount, %source_map);
  238.  
  239. # Generated docbook code is inserted in a template at a point where
  240. # docbook v3.1 requires a non-zero sequence of RefEntry's; see:
  241. # http://www.oasis-open.org/docbook/documentation/reference/html/refentry.html
  242. # We keep track of number of generated entries and generate a dummy
  243. # if needs be to ensure the expanded template can be postprocessed
  244. # into html.
  245. my $section_counter = 0;
  246.  
  247. my $lineprefix="";
  248.  
  249. # states
  250. # 0 - normal code
  251. # 1 - looking for function name
  252. # 2 - scanning field start.
  253. # 3 - scanning prototype.
  254. # 4 - documentation block
  255. my $state;
  256. my $in_doc_sect;
  257.  
  258. #declaration types: can be
  259. # 'function', 'struct', 'union', 'enum', 'typedef'
  260. my $decl_type;
  261.  
  262. my $doc_special = "\@\%\$\&";
  263.  
  264. my $doc_start = '^/\*\*\s*$'; # Allow whitespace at end of comment start.
  265. my $doc_end = '\*/';
  266. my $doc_com = '\s*\*\s*';
  267. my $doc_decl = $doc_com.'(\w+)';
  268. my $doc_sect = $doc_com.'(['.$doc_special.']?[\w ]+):(.*)';
  269. my $doc_content = $doc_com.'(.*)';
  270. my $doc_block = $doc_com.'DOC:\s*(.*)?';
  271.  
  272. my %constants;
  273. my %parameterdescs;
  274. my @parameterlist;
  275. my %sections;
  276. my @sectionlist;
  277.  
  278. my $contents = "";
  279. my $section_default = "Description";    # default section
  280. my $section_intro = "Introduction";
  281. my $section = $section_default;
  282. my $section_context = "Context";
  283.  
  284. my $undescribed = "-- undescribed --";
  285.  
  286. reset_state();
  287.  
  288. while ($ARGV[0] =~ m/^-(.*)/) {
  289.     my $cmd = shift @ARGV;
  290.     if ($cmd eq "-html") {
  291.     $output_mode = "html";
  292.     %highlights = %highlights_html;
  293.     $blankline = $blankline_html;
  294.     } elsif ($cmd eq "-man") {
  295.     $output_mode = "man";
  296.     %highlights = %highlights_man;
  297.     $blankline = $blankline_man;
  298.     } elsif ($cmd eq "-text") {
  299.     $output_mode = "text";
  300.     %highlights = %highlights_text;
  301.     $blankline = $blankline_text;
  302.     } elsif ($cmd eq "-docbook") {
  303.     $output_mode = "xml";
  304.     %highlights = %highlights_xml;
  305.     $blankline = $blankline_xml;
  306.     } elsif ($cmd eq "-gnome") {
  307.     $output_mode = "gnome";
  308.     %highlights = %highlights_gnome;
  309.     $blankline = $blankline_gnome;
  310.     } elsif ($cmd eq "-module") { # not needed for XML, inherits from calling document
  311.     $modulename = shift @ARGV;
  312.     } elsif ($cmd eq "-function") { # to only output specific functions
  313.     $function_only = 1;
  314.     $function = shift @ARGV;
  315.     $function_table{$function} = 1;
  316.     } elsif ($cmd eq "-nofunction") { # to only output specific functions
  317.     $function_only = 2;
  318.     $function = shift @ARGV;
  319.     $function_table{$function} = 1;
  320.     } elsif ($cmd eq "-v") {
  321.     $verbose = 1;
  322.     } elsif (($cmd eq "-h") || ($cmd eq "--help")) {
  323.     usage();
  324.     } elsif ($cmd eq '-filelist') {
  325.         $filelist = shift @ARGV;
  326.     }
  327. }
  328.  
  329.  
  330. # generate a sequence of code that will splice in highlighting information
  331. # using the s// operator.
  332. my $dohighlight = "";
  333. foreach my $pattern (keys %highlights) {
  334. #    print "scanning pattern $pattern ($highlights{$pattern})\n";
  335.     $dohighlight .=  "\$contents =~ s:$pattern:$highlights{$pattern}:gs;\n";
  336. }
  337.  
  338. ##
  339. # dumps section contents to arrays/hashes intended for that purpose.
  340. #
  341. sub dump_section {
  342.     my $name = shift;
  343.     my $contents = join "\n", @_;
  344.  
  345.     if ($name =~ m/$type_constant/) {
  346.     $name = $1;
  347. #    print STDERR "constant section '$1' = '$contents'\n";
  348.     $constants{$name} = $contents;
  349.     } elsif ($name =~ m/$type_param/) {
  350. #    print STDERR "parameter def '$1' = '$contents'\n";
  351.     $name = $1;
  352.     $parameterdescs{$name} = $contents;
  353.     } else {
  354. #    print STDERR "other section '$name' = '$contents'\n";
  355.     $sections{$name} = $contents;
  356.     push @sectionlist, $name;
  357.     }
  358. }
  359.  
  360. ##
  361. # output function
  362. #
  363. # parameterdescs, a hash.
  364. #  function => "function name"
  365. #  parameterlist => @list of parameters
  366. #  parameterdescs => %parameter descriptions
  367. #  sectionlist => @list of sections
  368. #  sections => %descriont descriptions
  369. #
  370.  
  371. sub output_highlight {
  372.     my $contents = join "\n",@_;
  373.     my $line;
  374.  
  375. #   DEBUG
  376. #   if (!defined $contents) {
  377. #    use Carp;
  378. #    confess "output_highlight got called with no args?\n";
  379. #   }
  380.  
  381.     eval $dohighlight;
  382.     die $@ if $@;
  383.     foreach $line (split "\n", $contents) {
  384.       if ($line eq ""){
  385.         print $lineprefix, $blankline;
  386.     } else {
  387.             $line =~ s/\\\\\\/\&/g;
  388.         print $lineprefix, $line;
  389.     }
  390.     print "\n";
  391.     }
  392. }
  393.  
  394. #output sections in html
  395. sub output_section_html(%) {
  396.     my %args = %{$_[0]};
  397.     my $section;
  398.  
  399.     foreach $section (@{$args{'sectionlist'}}) {
  400.     print "<h3>$section</h3>\n";
  401.     print "<blockquote>\n";
  402.     output_highlight($args{'sections'}{$section});
  403.     print "</blockquote>\n";
  404.     }
  405. }
  406.  
  407. # output enum in html
  408. sub output_enum_html(%) {
  409.     my %args = %{$_[0]};
  410.     my ($parameter);
  411.     my $count;
  412.     print "<h2>enum ".$args{'enum'}."</h2>\n";
  413.  
  414.     print "<b>enum ".$args{'enum'}."</b> {<br>\n";
  415.     $count = 0;
  416.     foreach $parameter (@{$args{'parameterlist'}}) {
  417.         print " <b>".$parameter."</b>";
  418.     if ($count != $#{$args{'parameterlist'}}) {
  419.         $count++;
  420.         print ",\n";
  421.     }
  422.     print "<br>";
  423.     }
  424.     print "};<br>\n";
  425.  
  426.     print "<h3>Constants</h3>\n";
  427.     print "<dl>\n";
  428.     foreach $parameter (@{$args{'parameterlist'}}) {
  429.     print "<dt><b>".$parameter."</b>\n";
  430.     print "<dd>";
  431.     output_highlight($args{'parameterdescs'}{$parameter});
  432.     }
  433.     print "</dl>\n";
  434.     output_section_html(@_);
  435.     print "<hr>\n";
  436. }
  437.  
  438. # output typedef in html
  439. sub output_typedef_html(%) {
  440.     my %args = %{$_[0]};
  441.     my ($parameter);
  442.     my $count;
  443.     print "<h2>typedef ".$args{'typedef'}."</h2>\n";
  444.  
  445.     print "<b>typedef ".$args{'typedef'}."</b>\n";
  446.     output_section_html(@_);
  447.     print "<hr>\n";
  448. }
  449.  
  450. # output struct in html
  451. sub output_struct_html(%) {
  452.     my %args = %{$_[0]};
  453.     my ($parameter);
  454.  
  455.     print "<h2>".$args{'type'}." ".$args{'struct'}."</h2>\n";
  456.     print "<b>".$args{'type'}." ".$args{'struct'}."</b> {<br>\n";
  457.     foreach $parameter (@{$args{'parameterlist'}}) {
  458.     if ($parameter =~ /^#/) {
  459.         print "$parameter<br>\n";
  460.         next;
  461.     }
  462.     my $parameter_name = $parameter;
  463.     $parameter_name =~ s/\[.*//;
  464.  
  465.         ($args{'parameterdescs'}{$parameter_name} ne $undescribed) || next;
  466.     $type = $args{'parametertypes'}{$parameter};
  467.     if ($type =~ m/([^\(]*\(\*)\s*\)\s*\(([^\)]*)\)/) {
  468.         # pointer-to-function
  469.         print " <i>$1</i><b>$parameter</b>) <i>($2)</i>;<br>\n";
  470.     } elsif ($type =~ m/^(.*?)\s*(:.*)/) {
  471.         print " <i>$1</i> <b>$parameter</b>$2;<br>\n";
  472.     } else {
  473.         print " <i>$type</i> <b>$parameter</b>;<br>\n";
  474.     }
  475.     }
  476.     print "};<br>\n";
  477.  
  478.     print "<h3>Members</h3>\n";
  479.     print "<dl>\n";
  480.     foreach $parameter (@{$args{'parameterlist'}}) {
  481.     ($parameter =~ /^#/) && next;
  482.  
  483.     my $parameter_name = $parameter;
  484.     $parameter_name =~ s/\[.*//;
  485.  
  486.         ($args{'parameterdescs'}{$parameter_name} ne $undescribed) || next;
  487.     print "<dt><b>".$parameter."</b>\n";
  488.     print "<dd>";
  489.     output_highlight($args{'parameterdescs'}{$parameter_name});
  490.     }
  491.     print "</dl>\n";
  492.     output_section_html(@_);
  493.     print "<hr>\n";
  494. }
  495.  
  496. # output function in html
  497. sub output_function_html(%) {
  498.     my %args = %{$_[0]};
  499.     my ($parameter, $section);
  500.     my $count;
  501.     print "<h2>Function</h2>\n";
  502.  
  503.     print "<i>".$args{'functiontype'}."</i>\n";
  504.     print "<b>".$args{'function'}."</b>\n";
  505.     print "(";
  506.     $count = 0;
  507.     foreach $parameter (@{$args{'parameterlist'}}) {
  508.     $type = $args{'parametertypes'}{$parameter};
  509.     if ($type =~ m/([^\(]*\(\*)\s*\)\s*\(([^\)]*)\)/) {
  510.         # pointer-to-function
  511.         print "<i>$1</i><b>$parameter</b>) <i>($2)</i>";
  512.     } else {
  513.         print "<i>".$type."</i> <b>".$parameter."</b>";
  514.     }
  515.     if ($count != $#{$args{'parameterlist'}}) {
  516.         $count++;
  517.         print ",\n";
  518.     }
  519.     }
  520.     print ")\n";
  521.  
  522.     print "<h3>Arguments</h3>\n";
  523.     print "<dl>\n";
  524.     foreach $parameter (@{$args{'parameterlist'}}) {
  525.     my $parameter_name = $parameter;
  526.     $parameter_name =~ s/\[.*//;
  527.  
  528.         ($args{'parameterdescs'}{$parameter_name} ne $undescribed) || next;
  529.     print "<dt><b>".$parameter."</b>\n";
  530.     print "<dd>";
  531.     output_highlight($args{'parameterdescs'}{$parameter_name});
  532.     }
  533.     print "</dl>\n";
  534.     output_section_html(@_);
  535.     print "<hr>\n";
  536. }
  537.  
  538. # output intro in html
  539. sub output_intro_html(%) {
  540.     my %args = %{$_[0]};
  541.     my ($parameter, $section);
  542.     my $count;
  543.  
  544.     foreach $section (@{$args{'sectionlist'}}) {
  545.     print "<h3>$section</h3>\n";
  546.     print "<ul>\n";
  547.     output_highlight($args{'sections'}{$section});
  548.     print "</ul>\n";
  549.     }
  550.     print "<hr>\n";
  551. }
  552.  
  553. sub output_section_xml(%) {
  554.     my %args = %{$_[0]};
  555.     my $section;
  556.     # print out each section
  557.     $lineprefix="   ";
  558.     foreach $section (@{$args{'sectionlist'}}) {
  559.     print "<refsect1>\n";
  560.     print "<title>$section</title>\n";
  561.     if ($section =~ m/EXAMPLE/i) {
  562.         print "<informalexample><programlisting>\n";
  563.     } else {
  564.         print "<para>\n";
  565.     }
  566.     output_highlight($args{'sections'}{$section});
  567.     if ($section =~ m/EXAMPLE/i) {
  568.         print "</programlisting></informalexample>\n";
  569.     } else {
  570.         print "</para>\n";
  571.     }
  572.     print "</refsect1>\n";
  573.     }
  574. }
  575.  
  576. # output function in XML DocBook
  577. sub output_function_xml(%) {
  578.     my %args = %{$_[0]};
  579.     my ($parameter, $section);
  580.     my $count;
  581.     my $id;
  582.  
  583.     $id = "API-".$args{'function'};
  584.     $id =~ s/[^A-Za-z0-9]/-/g;
  585.  
  586.     print "<refentry>\n";
  587.     print "<refentryinfo>\n";
  588.     print " <title>LINUX</title>\n";
  589.     print " <productname>Kernel Hackers Manual</productname>\n";
  590.     print " <date>$man_date</date>\n";
  591.     print "</refentryinfo>\n";
  592.     print "<refmeta>\n";
  593.     print " <refentrytitle><phrase id=\"$id\">".$args{'function'}."</phrase></refentrytitle>\n";
  594.     print " <manvolnum>9</manvolnum>\n";
  595.     print "</refmeta>\n";
  596.     print "<refnamediv>\n";
  597.     print " <refname>".$args{'function'}."</refname>\n";
  598.     print " <refpurpose>\n";
  599.     print "  ";
  600.     output_highlight ($args{'purpose'});
  601.     print " </refpurpose>\n";
  602.     print "</refnamediv>\n";
  603.  
  604.     print "<refsynopsisdiv>\n";
  605.     print " <title>Synopsis</title>\n";
  606.     print "  <funcsynopsis><funcprototype>\n";
  607.     print "   <funcdef>".$args{'functiontype'}." ";
  608.     print "<function>".$args{'function'}." </function></funcdef>\n";
  609.  
  610.     $count = 0;
  611.     if ($#{$args{'parameterlist'}} >= 0) {
  612.     foreach $parameter (@{$args{'parameterlist'}}) {
  613.         $type = $args{'parametertypes'}{$parameter};
  614.         if ($type =~ m/([^\(]*\(\*)\s*\)\s*\(([^\)]*)\)/) {
  615.         # pointer-to-function
  616.         print "   <paramdef>$1<parameter>$parameter</parameter>)\n";
  617.         print "     <funcparams>$2</funcparams></paramdef>\n";
  618.         } else {
  619.         print "   <paramdef>".$type;
  620.         print " <parameter>$parameter</parameter></paramdef>\n";
  621.         }
  622.     }
  623.     } else {
  624.     print "  <void/>\n";
  625.     }
  626.     print "  </funcprototype></funcsynopsis>\n";
  627.     print "</refsynopsisdiv>\n";
  628.  
  629.     # print parameters
  630.     print "<refsect1>\n <title>Arguments</title>\n";
  631.     if ($#{$args{'parameterlist'}} >= 0) {
  632.     print " <variablelist>\n";
  633.     foreach $parameter (@{$args{'parameterlist'}}) {
  634.         my $parameter_name = $parameter;
  635.         $parameter_name =~ s/\[.*//;
  636.  
  637.         print "  <varlistentry>\n   <term><parameter>$parameter</parameter></term>\n";
  638.         print "   <listitem>\n    <para>\n";
  639.         $lineprefix="     ";
  640.         output_highlight($args{'parameterdescs'}{$parameter_name});
  641.         print "    </para>\n   </listitem>\n  </varlistentry>\n";
  642.     }
  643.     print " </variablelist>\n";
  644.     } else {
  645.     print " <para>\n  None\n </para>\n";
  646.     }
  647.     print "</refsect1>\n";
  648.  
  649.     output_section_xml(@_);
  650.     print "</refentry>\n\n";
  651. }
  652.  
  653. # output struct in XML DocBook
  654. sub output_struct_xml(%) {
  655.     my %args = %{$_[0]};
  656.     my ($parameter, $section);
  657.     my $id;
  658.  
  659.     $id = "API-struct-".$args{'struct'};
  660.     $id =~ s/[^A-Za-z0-9]/-/g;
  661.  
  662.     print "<refentry>\n";
  663.     print "<refentryinfo>\n";
  664.     print " <title>LINUX</title>\n";
  665.     print " <productname>Kernel Hackers Manual</productname>\n";
  666.     print " <date>$man_date</date>\n";
  667.     print "</refentryinfo>\n";
  668.     print "<refmeta>\n";
  669.     print " <refentrytitle><phrase id=\"$id\">".$args{'type'}." ".$args{'struct'}."</phrase></refentrytitle>\n";
  670.     print " <manvolnum>9</manvolnum>\n";
  671.     print "</refmeta>\n";
  672.     print "<refnamediv>\n";
  673.     print " <refname>".$args{'type'}." ".$args{'struct'}."</refname>\n";
  674.     print " <refpurpose>\n";
  675.     print "  ";
  676.     output_highlight ($args{'purpose'});
  677.     print " </refpurpose>\n";
  678.     print "</refnamediv>\n";
  679.  
  680.     print "<refsynopsisdiv>\n";
  681.     print " <title>Synopsis</title>\n";
  682.     print "  <programlisting>\n";
  683.     print $args{'type'}." ".$args{'struct'}." {\n";
  684.     foreach $parameter (@{$args{'parameterlist'}}) {
  685.     if ($parameter =~ /^#/) {
  686.         print "$parameter\n";
  687.         next;
  688.     }
  689.  
  690.     my $parameter_name = $parameter;
  691.     $parameter_name =~ s/\[.*//;
  692.  
  693.     defined($args{'parameterdescs'}{$parameter_name}) || next;
  694.         ($args{'parameterdescs'}{$parameter_name} ne $undescribed) || next;
  695.     $type = $args{'parametertypes'}{$parameter};
  696.     if ($type =~ m/([^\(]*\(\*)\s*\)\s*\(([^\)]*)\)/) {
  697.         # pointer-to-function
  698.         print "  $1 $parameter) ($2);\n";
  699.     } elsif ($type =~ m/^(.*?)\s*(:.*)/) {
  700.         print "  $1 $parameter$2;\n";
  701.     } else {
  702.         print "  ".$type." ".$parameter.";\n";
  703.     }
  704.     }
  705.     print "};";
  706.     print "  </programlisting>\n";
  707.     print "</refsynopsisdiv>\n";
  708.  
  709.     print " <refsect1>\n";
  710.     print "  <title>Members</title>\n";
  711.  
  712.     print "  <variablelist>\n";
  713.     foreach $parameter (@{$args{'parameterlist'}}) {
  714.       ($parameter =~ /^#/) && next;
  715.  
  716.       my $parameter_name = $parameter;
  717.       $parameter_name =~ s/\[.*//;
  718.  
  719.       defined($args{'parameterdescs'}{$parameter_name}) || next;
  720.       ($args{'parameterdescs'}{$parameter_name} ne $undescribed) || next;
  721.       print "    <varlistentry>";
  722.       print "      <term>$parameter</term>\n";
  723.       print "      <listitem><para>\n";
  724.       output_highlight($args{'parameterdescs'}{$parameter_name});
  725.       print "      </para></listitem>\n";
  726.       print "    </varlistentry>\n";
  727.     }
  728.     print "  </variablelist>\n";
  729.     print " </refsect1>\n";
  730.  
  731.     output_section_xml(@_);
  732.  
  733.     print "</refentry>\n\n";
  734. }
  735.  
  736. # output enum in XML DocBook
  737. sub output_enum_xml(%) {
  738.     my %args = %{$_[0]};
  739.     my ($parameter, $section);
  740.     my $count;
  741.     my $id;
  742.  
  743.     $id = "API-enum-".$args{'enum'};
  744.     $id =~ s/[^A-Za-z0-9]/-/g;
  745.  
  746.     print "<refentry>\n";
  747.     print "<refentryinfo>\n";
  748.     print " <title>LINUX</title>\n";
  749.     print " <productname>Kernel Hackers Manual</productname>\n";
  750.     print " <date>$man_date</date>\n";
  751.     print "</refentryinfo>\n";
  752.     print "<refmeta>\n";
  753.     print " <refentrytitle><phrase id=\"$id\">enum ".$args{'enum'}."</phrase></refentrytitle>\n";
  754.     print " <manvolnum>9</manvolnum>\n";
  755.     print "</refmeta>\n";
  756.     print "<refnamediv>\n";
  757.     print " <refname>enum ".$args{'enum'}."</refname>\n";
  758.     print " <refpurpose>\n";
  759.     print "  ";
  760.     output_highlight ($args{'purpose'});
  761.     print " </refpurpose>\n";
  762.     print "</refnamediv>\n";
  763.  
  764.     print "<refsynopsisdiv>\n";
  765.     print " <title>Synopsis</title>\n";
  766.     print "  <programlisting>\n";
  767.     print "enum ".$args{'enum'}." {\n";
  768.     $count = 0;
  769.     foreach $parameter (@{$args{'parameterlist'}}) {
  770.         print "  $parameter";
  771.         if ($count != $#{$args{'parameterlist'}}) {
  772.         $count++;
  773.         print ",";
  774.         }
  775.     print "\n";
  776.     }
  777.     print "};";
  778.     print "  </programlisting>\n";
  779.     print "</refsynopsisdiv>\n";
  780.  
  781.     print "<refsect1>\n";
  782.     print " <title>Constants</title>\n";
  783.     print "  <variablelist>\n";
  784.     foreach $parameter (@{$args{'parameterlist'}}) {
  785.       my $parameter_name = $parameter;
  786.       $parameter_name =~ s/\[.*//;
  787.  
  788.       print "    <varlistentry>";
  789.       print "      <term>$parameter</term>\n";
  790.       print "      <listitem><para>\n";
  791.       output_highlight($args{'parameterdescs'}{$parameter_name});
  792.       print "      </para></listitem>\n";
  793.       print "    </varlistentry>\n";
  794.     }
  795.     print "  </variablelist>\n";
  796.     print "</refsect1>\n";
  797.  
  798.     output_section_xml(@_);
  799.  
  800.     print "</refentry>\n\n";
  801. }
  802.  
  803. # output typedef in XML DocBook
  804. sub output_typedef_xml(%) {
  805.     my %args = %{$_[0]};
  806.     my ($parameter, $section);
  807.     my $id;
  808.  
  809.     $id = "API-typedef-".$args{'typedef'};
  810.     $id =~ s/[^A-Za-z0-9]/-/g;
  811.  
  812.     print "<refentry>\n";
  813.     print "<refentryinfo>\n";
  814.     print " <title>LINUX</title>\n";
  815.     print " <productname>Kernel Hackers Manual</productname>\n";
  816.     print " <date>$man_date</date>\n";
  817.     print "</refentryinfo>\n";
  818.     print "<refmeta>\n";
  819.     print " <refentrytitle><phrase id=\"$id\">typedef ".$args{'typedef'}."</phrase></refentrytitle>\n";
  820.     print " <manvolnum>9</manvolnum>\n";
  821.     print "</refmeta>\n";
  822.     print "<refnamediv>\n";
  823.     print " <refname>typedef ".$args{'typedef'}."</refname>\n";
  824.     print " <refpurpose>\n";
  825.     print "  ";
  826.     output_highlight ($args{'purpose'});
  827.     print " </refpurpose>\n";
  828.     print "</refnamediv>\n";
  829.  
  830.     print "<refsynopsisdiv>\n";
  831.     print " <title>Synopsis</title>\n";
  832.     print "  <synopsis>typedef ".$args{'typedef'}.";</synopsis>\n";
  833.     print "</refsynopsisdiv>\n";
  834.  
  835.     output_section_xml(@_);
  836.  
  837.     print "</refentry>\n\n";
  838. }
  839.  
  840. # output in XML DocBook
  841. sub output_intro_xml(%) {
  842.     my %args = %{$_[0]};
  843.     my ($parameter, $section);
  844.     my $count;
  845.  
  846.     my $id = $args{'module'};
  847.     $id =~ s/[^A-Za-z0-9]/-/g;
  848.  
  849.     # print out each section
  850.     $lineprefix="   ";
  851.     foreach $section (@{$args{'sectionlist'}}) {
  852.     print "<refsect1>\n <title>$section</title>\n <para>\n";
  853.     if ($section =~ m/EXAMPLE/i) {
  854.         print "<example><para>\n";
  855.     }
  856.     output_highlight($args{'sections'}{$section});
  857.     if ($section =~ m/EXAMPLE/i) {
  858.         print "</para></example>\n";
  859.     }
  860.     print " </para>\n</refsect1>\n";
  861.     }
  862.  
  863.     print "\n\n";
  864. }
  865.  
  866. # output in XML DocBook
  867. sub output_function_gnome {
  868.     my %args = %{$_[0]};
  869.     my ($parameter, $section);
  870.     my $count;
  871.     my $id;
  872.  
  873.     $id = $args{'module'}."-".$args{'function'};
  874.     $id =~ s/[^A-Za-z0-9]/-/g;
  875.  
  876.     print "<sect2>\n";
  877.     print " <title id=\"$id\">".$args{'function'}."</title>\n";
  878.  
  879.     print "  <funcsynopsis>\n";
  880.     print "   <funcdef>".$args{'functiontype'}." ";
  881.     print "<function>".$args{'function'}." ";
  882.     print "</function></funcdef>\n";
  883.  
  884.     $count = 0;
  885.     if ($#{$args{'parameterlist'}} >= 0) {
  886.     foreach $parameter (@{$args{'parameterlist'}}) {
  887.         $type = $args{'parametertypes'}{$parameter};
  888.         if ($type =~ m/([^\(]*\(\*)\s*\)\s*\(([^\)]*)\)/) {
  889.         # pointer-to-function
  890.         print "   <paramdef>$1 <parameter>$parameter</parameter>)\n";
  891.         print "     <funcparams>$2</funcparams></paramdef>\n";
  892.         } else {
  893.         print "   <paramdef>".$type;
  894.         print " <parameter>$parameter</parameter></paramdef>\n";
  895.         }
  896.     }
  897.     } else {
  898.     print "  <void>\n";
  899.     }
  900.     print "  </funcsynopsis>\n";
  901.     if ($#{$args{'parameterlist'}} >= 0) {
  902.     print " <informaltable pgwide=\"1\" frame=\"none\" role=\"params\">\n";
  903.     print "<tgroup cols=\"2\">\n";
  904.     print "<colspec colwidth=\"2*\">\n";
  905.     print "<colspec colwidth=\"8*\">\n";
  906.     print "<tbody>\n";
  907.     foreach $parameter (@{$args{'parameterlist'}}) {
  908.         my $parameter_name = $parameter;
  909.         $parameter_name =~ s/\[.*//;
  910.  
  911.         print "  <row><entry align=\"right\"><parameter>$parameter</parameter></entry>\n";
  912.         print "   <entry>\n";
  913.         $lineprefix="     ";
  914.         output_highlight($args{'parameterdescs'}{$parameter_name});
  915.         print "    </entry></row>\n";
  916.     }
  917.     print " </tbody></tgroup></informaltable>\n";
  918.     } else {
  919.     print " <para>\n  None\n </para>\n";
  920.     }
  921.  
  922.     # print out each section
  923.     $lineprefix="   ";
  924.     foreach $section (@{$args{'sectionlist'}}) {
  925.     print "<simplesect>\n <title>$section</title>\n";
  926.     if ($section =~ m/EXAMPLE/i) {
  927.         print "<example><programlisting>\n";
  928.     } else {
  929.     }
  930.     print "<para>\n";
  931.     output_highlight($args{'sections'}{$section});
  932.     print "</para>\n";
  933.     if ($section =~ m/EXAMPLE/i) {
  934.         print "</programlisting></example>\n";
  935.     } else {
  936.     }
  937.     print " </simplesect>\n";
  938.     }
  939.  
  940.     print "</sect2>\n\n";
  941. }
  942.  
  943. ##
  944. # output function in man
  945. sub output_function_man(%) {
  946.     my %args = %{$_[0]};
  947.     my ($parameter, $section);
  948.     my $count;
  949.  
  950.     print ".TH \"$args{'function'}\" 9 \"$args{'function'}\" \"$man_date\" \"Kernel Hacker's Manual\" LINUX\n";
  951.  
  952.     print ".SH NAME\n";
  953.     print $args{'function'}." \\- ".$args{'purpose'}."\n";
  954.  
  955.     print ".SH SYNOPSIS\n";
  956.     print ".B \"".$args{'functiontype'}."\" ".$args{'function'}."\n";
  957.     $count = 0;
  958.     my $parenth = "(";
  959.     my $post = ",";
  960.     foreach my $parameter (@{$args{'parameterlist'}}) {
  961.     if ($count == $#{$args{'parameterlist'}}) {
  962.         $post = ");";
  963.     }
  964.     $type = $args{'parametertypes'}{$parameter};
  965.     if ($type =~ m/([^\(]*\(\*)\s*\)\s*\(([^\)]*)\)/) {
  966.         # pointer-to-function
  967.         print ".BI \"".$parenth.$1."\" ".$parameter." \") (".$2.")".$post."\"\n";
  968.     } else {
  969.         $type =~ s/([^\*])$/$1 /;
  970.         print ".BI \"".$parenth.$type."\" ".$parameter." \"".$post."\"\n";
  971.     }
  972.     $count++;
  973.     $parenth = "";
  974.     }
  975.  
  976.     print ".SH ARGUMENTS\n";
  977.     foreach $parameter (@{$args{'parameterlist'}}) {
  978.     my $parameter_name = $parameter;
  979.     $parameter_name =~ s/\[.*//;
  980.  
  981.     print ".IP \"".$parameter."\" 12\n";
  982.     output_highlight($args{'parameterdescs'}{$parameter_name});
  983.     }
  984.     foreach $section (@{$args{'sectionlist'}}) {
  985.     print ".SH \"", uc $section, "\"\n";
  986.     output_highlight($args{'sections'}{$section});
  987.     }
  988. }
  989.  
  990. ##
  991. # output enum in man
  992. sub output_enum_man(%) {
  993.     my %args = %{$_[0]};
  994.     my ($parameter, $section);
  995.     my $count;
  996.  
  997.     print ".TH \"$args{'module'}\" 9 \"enum $args{'enum'}\" \"$man_date\" \"API Manual\" LINUX\n";
  998.  
  999.     print ".SH NAME\n";
  1000.     print "enum ".$args{'enum'}." \\- ".$args{'purpose'}."\n";
  1001.  
  1002.     print ".SH SYNOPSIS\n";
  1003.     print "enum ".$args{'enum'}." {\n";
  1004.     $count = 0;
  1005.     foreach my $parameter (@{$args{'parameterlist'}}) {
  1006.         print ".br\n.BI \"    $parameter\"\n";
  1007.     if ($count == $#{$args{'parameterlist'}}) {
  1008.         print "\n};\n";
  1009.         last;
  1010.     }
  1011.     else {
  1012.         print ", \n.br\n";
  1013.     }
  1014.     $count++;
  1015.     }
  1016.  
  1017.     print ".SH Constants\n";
  1018.     foreach $parameter (@{$args{'parameterlist'}}) {
  1019.     my $parameter_name = $parameter;
  1020.     $parameter_name =~ s/\[.*//;
  1021.  
  1022.     print ".IP \"".$parameter."\" 12\n";
  1023.     output_highlight($args{'parameterdescs'}{$parameter_name});
  1024.     }
  1025.     foreach $section (@{$args{'sectionlist'}}) {
  1026.     print ".SH \"$section\"\n";
  1027.     output_highlight($args{'sections'}{$section});
  1028.     }
  1029. }
  1030.  
  1031. ##
  1032. # output struct in man
  1033. sub output_struct_man(%) {
  1034.     my %args = %{$_[0]};
  1035.     my ($parameter, $section);
  1036.  
  1037.     print ".TH \"$args{'module'}\" 9 \"".$args{'type'}." ".$args{'struct'}."\" \"$man_date\" \"API Manual\" LINUX\n";
  1038.  
  1039.     print ".SH NAME\n";
  1040.     print $args{'type'}." ".$args{'struct'}." \\- ".$args{'purpose'}."\n";
  1041.  
  1042.     print ".SH SYNOPSIS\n";
  1043.     print $args{'type'}." ".$args{'struct'}." {\n.br\n";
  1044.  
  1045.     foreach my $parameter (@{$args{'parameterlist'}}) {
  1046.     if ($parameter =~ /^#/) {
  1047.         print ".BI \"$parameter\"\n.br\n";
  1048.         next;
  1049.     }
  1050.     my $parameter_name = $parameter;
  1051.     $parameter_name =~ s/\[.*//;
  1052.  
  1053.         ($args{'parameterdescs'}{$parameter_name} ne $undescribed) || next;
  1054.     $type = $args{'parametertypes'}{$parameter};
  1055.     if ($type =~ m/([^\(]*\(\*)\s*\)\s*\(([^\)]*)\)/) {
  1056.         # pointer-to-function
  1057.         print ".BI \"    ".$1."\" ".$parameter." \") (".$2.")"."\"\n;\n";
  1058.     } elsif ($type =~ m/^(.*?)\s*(:.*)/) {
  1059.         # bitfield
  1060.         print ".BI \"    ".$1."\ \" ".$parameter.$2." \""."\"\n;\n";
  1061.     } else {
  1062.         $type =~ s/([^\*])$/$1 /;
  1063.         print ".BI \"    ".$type."\" ".$parameter." \""."\"\n;\n";
  1064.     }
  1065.     print "\n.br\n";
  1066.     }
  1067.     print "};\n.br\n";
  1068.  
  1069.     print ".SH Members\n";
  1070.     foreach $parameter (@{$args{'parameterlist'}}) {
  1071.     ($parameter =~ /^#/) && next;
  1072.  
  1073.     my $parameter_name = $parameter;
  1074.     $parameter_name =~ s/\[.*//;
  1075.  
  1076.         ($args{'parameterdescs'}{$parameter_name} ne $undescribed) || next;
  1077.     print ".IP \"".$parameter."\" 12\n";
  1078.     output_highlight($args{'parameterdescs'}{$parameter_name});
  1079.     }
  1080.     foreach $section (@{$args{'sectionlist'}}) {
  1081.     print ".SH \"$section\"\n";
  1082.     output_highlight($args{'sections'}{$section});
  1083.     }
  1084. }
  1085.  
  1086. ##
  1087. # output typedef in man
  1088. sub output_typedef_man(%) {
  1089.     my %args = %{$_[0]};
  1090.     my ($parameter, $section);
  1091.  
  1092.     print ".TH \"$args{'module'}\" 9 \"$args{'typedef'}\" \"$man_date\" \"API Manual\" LINUX\n";
  1093.  
  1094.     print ".SH NAME\n";
  1095.     print "typedef ".$args{'typedef'}." \\- ".$args{'purpose'}."\n";
  1096.  
  1097.     foreach $section (@{$args{'sectionlist'}}) {
  1098.     print ".SH \"$section\"\n";
  1099.     output_highlight($args{'sections'}{$section});
  1100.     }
  1101. }
  1102.  
  1103. sub output_intro_man(%) {
  1104.     my %args = %{$_[0]};
  1105.     my ($parameter, $section);
  1106.     my $count;
  1107.  
  1108.     print ".TH \"$args{'module'}\" 9 \"$args{'module'}\" \"$man_date\" \"API Manual\" LINUX\n";
  1109.  
  1110.     foreach $section (@{$args{'sectionlist'}}) {
  1111.     print ".SH \"$section\"\n";
  1112.     output_highlight($args{'sections'}{$section});
  1113.     }
  1114. }
  1115.  
  1116. ##
  1117. # output in text
  1118. sub output_function_text(%) {
  1119.     my %args = %{$_[0]};
  1120.     my ($parameter, $section);
  1121.  
  1122.     print "Name:\n\n";
  1123.     print $args{'function'}." - ".$args{'purpose'}."\n";
  1124.  
  1125.     print "\nSynopsis:\n\n";
  1126.     my $start=$args{'functiontype'}." ".$args{'function'}." (";
  1127.     print $start;
  1128.     my $count = 0;
  1129.     foreach my $parameter (@{$args{'parameterlist'}}) {
  1130.     $type = $args{'parametertypes'}{$parameter};
  1131.     if ($type =~ m/([^\(]*\(\*)\s*\)\s*\(([^\)]*)\)/) {
  1132.         # pointer-to-function
  1133.         print $1.$parameter.") (".$2;
  1134.     } else {
  1135.         print $type." ".$parameter;
  1136.     }
  1137.     if ($count != $#{$args{'parameterlist'}}) {
  1138.         $count++;
  1139.         print ",\n";
  1140.         print " " x length($start);
  1141.     } else {
  1142.         print ");\n\n";
  1143.     }
  1144.     }
  1145.  
  1146.     print "Arguments:\n\n";
  1147.     foreach $parameter (@{$args{'parameterlist'}}) {
  1148.     my $parameter_name = $parameter;
  1149.     $parameter_name =~ s/\[.*//;
  1150.  
  1151.     print $parameter."\n\t".$args{'parameterdescs'}{$parameter_name}."\n";
  1152.     }
  1153.     output_section_text(@_);
  1154. }
  1155.  
  1156. #output sections in text
  1157. sub output_section_text(%) {
  1158.     my %args = %{$_[0]};
  1159.     my $section;
  1160.  
  1161.     print "\n";
  1162.     foreach $section (@{$args{'sectionlist'}}) {
  1163.     print "$section:\n\n";
  1164.     output_highlight($args{'sections'}{$section});
  1165.     }
  1166.     print "\n\n";
  1167. }
  1168.  
  1169. # output enum in text
  1170. sub output_enum_text(%) {
  1171.     my %args = %{$_[0]};
  1172.     my ($parameter);
  1173.     my $count;
  1174.     print "Enum:\n\n";
  1175.  
  1176.     print "enum ".$args{'enum'}." - ".$args{'purpose'}."\n\n";
  1177.     print "enum ".$args{'enum'}." {\n";
  1178.     $count = 0;
  1179.     foreach $parameter (@{$args{'parameterlist'}}) {
  1180.         print "\t$parameter";
  1181.     if ($count != $#{$args{'parameterlist'}}) {
  1182.         $count++;
  1183.         print ",";
  1184.     }
  1185.     print "\n";
  1186.     }
  1187.     print "};\n\n";
  1188.  
  1189.     print "Constants:\n\n";
  1190.     foreach $parameter (@{$args{'parameterlist'}}) {
  1191.     print "$parameter\n\t";
  1192.     print $args{'parameterdescs'}{$parameter}."\n";
  1193.     }
  1194.  
  1195.     output_section_text(@_);
  1196. }
  1197.  
  1198. # output typedef in text
  1199. sub output_typedef_text(%) {
  1200.     my %args = %{$_[0]};
  1201.     my ($parameter);
  1202.     my $count;
  1203.     print "Typedef:\n\n";
  1204.  
  1205.     print "typedef ".$args{'typedef'}." - ".$args{'purpose'}."\n";
  1206.     output_section_text(@_);
  1207. }
  1208.  
  1209. # output struct as text
  1210. sub output_struct_text(%) {
  1211.     my %args = %{$_[0]};
  1212.     my ($parameter);
  1213.  
  1214.     print $args{'type'}." ".$args{'struct'}." - ".$args{'purpose'}."\n\n";
  1215.     print $args{'type'}." ".$args{'struct'}." {\n";
  1216.     foreach $parameter (@{$args{'parameterlist'}}) {
  1217.     if ($parameter =~ /^#/) {
  1218.         print "$parameter\n";
  1219.         next;
  1220.     }
  1221.  
  1222.     my $parameter_name = $parameter;
  1223.     $parameter_name =~ s/\[.*//;
  1224.  
  1225.         ($args{'parameterdescs'}{$parameter_name} ne $undescribed) || next;
  1226.     $type = $args{'parametertypes'}{$parameter};
  1227.     if ($type =~ m/([^\(]*\(\*)\s*\)\s*\(([^\)]*)\)/) {
  1228.         # pointer-to-function
  1229.         print "\t$1 $parameter) ($2);\n";
  1230.     } elsif ($type =~ m/^(.*?)\s*(:.*)/) {
  1231.         print "\t$1 $parameter$2;\n";
  1232.     } else {
  1233.         print "\t".$type." ".$parameter.";\n";
  1234.     }
  1235.     }
  1236.     print "};\n\n";
  1237.  
  1238.     print "Members:\n\n";
  1239.     foreach $parameter (@{$args{'parameterlist'}}) {
  1240.     ($parameter =~ /^#/) && next;
  1241.  
  1242.     my $parameter_name = $parameter;
  1243.     $parameter_name =~ s/\[.*//;
  1244.  
  1245.         ($args{'parameterdescs'}{$parameter_name} ne $undescribed) || next;
  1246.     print "$parameter\n\t";
  1247.     print $args{'parameterdescs'}{$parameter_name}."\n";
  1248.     }
  1249.     print "\n";
  1250.     output_section_text(@_);
  1251. }
  1252.  
  1253. sub output_intro_text(%) {
  1254.     my %args = %{$_[0]};
  1255.     my ($parameter, $section);
  1256.  
  1257.     foreach $section (@{$args{'sectionlist'}}) {
  1258.     print " $section:\n";
  1259.     print "    -> ";
  1260.     output_highlight($args{'sections'}{$section});
  1261.     }
  1262. }
  1263.  
  1264. ##
  1265. # generic output function for all types (function, struct/union, typedef, enum);
  1266. # calls the generated, variable output_ function name based on
  1267. # functype and output_mode
  1268. sub output_declaration {
  1269.     no strict 'refs';
  1270.     my $name = shift;
  1271.     my $functype = shift;
  1272.     my $func = "output_${functype}_$output_mode";
  1273.     if (($function_only==0) ||
  1274.     ( $function_only == 1 && defined($function_table{$name})) ||
  1275.     ( $function_only == 2 && !defined($function_table{$name})))
  1276.     {
  1277.         &$func(@_);
  1278.     $section_counter++;
  1279.     }
  1280. }
  1281.  
  1282. ##
  1283. # generic output function - calls the right one based on current output mode.
  1284. sub output_intro {
  1285.     no strict 'refs';
  1286.     my $func = "output_intro_".$output_mode;
  1287.     &$func(@_);
  1288.     $section_counter++;
  1289. }
  1290.  
  1291. ##
  1292. # takes a declaration (struct, union, enum, typedef) and
  1293. # invokes the right handler. NOT called for functions.
  1294. sub dump_declaration($$) {
  1295.     no strict 'refs';
  1296.     my ($prototype, $file) = @_;
  1297.     my $func = "dump_".$decl_type;
  1298.     &$func(@_);
  1299. }
  1300.  
  1301. sub dump_union($$) {
  1302.     dump_struct(@_);
  1303. }
  1304.  
  1305. sub dump_struct($$) {
  1306.     my $x = shift;
  1307.     my $file = shift;
  1308.  
  1309.     if ($x =~/(struct|union)\s+(\w+)\s*{(.*)}/) {
  1310.         $declaration_name = $2;
  1311.         my $members = $3;
  1312.  
  1313.     # ignore embedded structs or unions
  1314.     $members =~ s/{.*?}//g;
  1315.  
  1316.     # ignore members marked private:
  1317.     $members =~ s/\/\*.*?private:.*?public:.*?\*\///gos;
  1318.     $members =~ s/\/\*.*?private:.*//gos;
  1319.     # strip comments:
  1320.     $members =~ s/\/\*.*?\*\///gos;
  1321.  
  1322.     create_parameterlist($members, ';', $file);
  1323.  
  1324.     output_declaration($declaration_name,
  1325.                'struct',
  1326.                {'struct' => $declaration_name,
  1327.                 'module' => $modulename,
  1328.                 'parameterlist' => \@parameterlist,
  1329.                 'parameterdescs' => \%parameterdescs,
  1330.                 'parametertypes' => \%parametertypes,
  1331.                 'sectionlist' => \@sectionlist,
  1332.                 'sections' => \%sections,
  1333.                 'purpose' => $declaration_purpose,
  1334.                 'type' => $decl_type
  1335.                });
  1336.     }
  1337.     else {
  1338.         print STDERR "Error(${file}:$.): Cannot parse struct or union!\n";
  1339.     ++$errors;
  1340.     }
  1341. }
  1342.  
  1343. sub dump_enum($$) {
  1344.     my $x = shift;
  1345.     my $file = shift;
  1346.  
  1347.     $x =~ s@/\*.*?\*/@@gos;    # strip comments.
  1348.     if ($x =~ /enum\s+(\w+)\s*{(.*)}/) {
  1349.         $declaration_name = $1;
  1350.         my $members = $2;
  1351.  
  1352.     foreach my $arg (split ',', $members) {
  1353.         $arg =~ s/^\s*(\w+).*/$1/;
  1354.         push @parameterlist, $arg;
  1355.         if (!$parameterdescs{$arg}) {
  1356.             $parameterdescs{$arg} = $undescribed;
  1357.             print STDERR "Warning(${file}:$.): Enum value '$arg' ".
  1358.             "not described in enum '$declaration_name'\n";
  1359.         }
  1360.  
  1361.     }
  1362.  
  1363.     output_declaration($declaration_name,
  1364.                'enum',
  1365.                {'enum' => $declaration_name,
  1366.                 'module' => $modulename,
  1367.                 'parameterlist' => \@parameterlist,
  1368.                 'parameterdescs' => \%parameterdescs,
  1369.                 'sectionlist' => \@sectionlist,
  1370.                 'sections' => \%sections,
  1371.                 'purpose' => $declaration_purpose
  1372.                });
  1373.     }
  1374.     else {
  1375.         print STDERR "Error(${file}:$.): Cannot parse enum!\n";
  1376.     ++$errors;
  1377.     }
  1378. }
  1379.  
  1380. sub dump_typedef($$) {
  1381.     my $x = shift;
  1382.     my $file = shift;
  1383.  
  1384.     $x =~ s@/\*.*?\*/@@gos;    # strip comments.
  1385.     while (($x =~ /\(*.\)\s*;$/) || ($x =~ /\[*.\]\s*;$/)) {
  1386.         $x =~ s/\(*.\)\s*;$/;/;
  1387.     $x =~ s/\[*.\]\s*;$/;/;
  1388.     }
  1389.  
  1390.     if ($x =~ /typedef.*\s+(\w+)\s*;/) {
  1391.         $declaration_name = $1;
  1392.  
  1393.     output_declaration($declaration_name,
  1394.                'typedef',
  1395.                {'typedef' => $declaration_name,
  1396.                 'module' => $modulename,
  1397.                 'sectionlist' => \@sectionlist,
  1398.                 'sections' => \%sections,
  1399.                 'purpose' => $declaration_purpose
  1400.                });
  1401.     }
  1402.     else {
  1403.         print STDERR "Error(${file}:$.): Cannot parse typedef!\n";
  1404.     ++$errors;
  1405.     }
  1406. }
  1407.  
  1408. sub create_parameterlist($$$) {
  1409.     my $args = shift;
  1410.     my $splitter = shift;
  1411.     my $file = shift;
  1412.     my $type;
  1413.     my $param;
  1414.  
  1415.     # temporarily replace commas inside function pointer definition
  1416.     while ($args =~ /(\([^\),]+),/) {
  1417.         $args =~ s/(\([^\),]+),/$1#/g;
  1418.     }
  1419.  
  1420.     foreach my $arg (split($splitter, $args)) {
  1421.     # strip comments
  1422.     $arg =~ s/\/\*.*\*\///;
  1423.         # strip leading/trailing spaces
  1424.         $arg =~ s/^\s*//;
  1425.     $arg =~ s/\s*$//;
  1426.     $arg =~ s/\s+/ /;
  1427.  
  1428.     if ($arg =~ /^#/) {
  1429.         # Treat preprocessor directive as a typeless variable just to fill
  1430.         # corresponding data structures "correctly". Catch it later in
  1431.         # output_* subs.
  1432.         push_parameter($arg, "", $file);
  1433.     } elsif ($arg =~ m/\(.*\*/) {
  1434.         # pointer-to-function
  1435.         $arg =~ tr/#/,/;
  1436.         $arg =~ m/[^\(]+\(\*([^\)]+)\)/;
  1437.         $param = $1;
  1438.         $type = $arg;
  1439.         $type =~ s/([^\(]+\(\*)$param/$1/;
  1440.         push_parameter($param, $type, $file);
  1441.     } elsif ($arg) {
  1442.         $arg =~ s/\s*:\s*/:/g;
  1443.         $arg =~ s/\s*\[/\[/g;
  1444.  
  1445.         my @args = split('\s*,\s*', $arg);
  1446.         if ($args[0] =~ m/\*/) {
  1447.         $args[0] =~ s/(\*+)\s*/ $1/;
  1448.         }
  1449.         my @first_arg = split('\s+', shift @args);
  1450.         unshift(@args, pop @first_arg);
  1451.         $type = join " ", @first_arg;
  1452.  
  1453.         foreach $param (@args) {
  1454.         if ($param =~ m/^(\*+)\s*(.*)/) {
  1455.             push_parameter($2, "$type $1", $file);
  1456.         }
  1457.         elsif ($param =~ m/(.*?):(\d+)/) {
  1458.             push_parameter($1, "$type:$2", $file)
  1459.         }
  1460.         else {
  1461.             push_parameter($param, $type, $file);
  1462.         }
  1463.         }
  1464.     }
  1465.     }
  1466. }
  1467.  
  1468. sub push_parameter($$$) {
  1469.     my $param = shift;
  1470.     my $type = shift;
  1471.     my $file = shift;
  1472.     my $anon = 0;
  1473.  
  1474.     my $param_name = $param;
  1475.     $param_name =~ s/\[.*//;
  1476.  
  1477.     if ($type eq "" && $param =~ /\.\.\.$/)
  1478.     {
  1479.         $type="";
  1480.         $parameterdescs{$param} = "variable arguments";
  1481.     }
  1482.     elsif ($type eq "" && ($param eq "" or $param eq "void"))
  1483.     {
  1484.         $type="";
  1485.         $param="void";
  1486.         $parameterdescs{void} = "no arguments";
  1487.     }
  1488.     elsif ($type eq "" && ($param eq "struct" or $param eq "union"))
  1489.     # handle unnamed (anonymous) union or struct:
  1490.     {
  1491.         $type = $param;
  1492.         $param = "{unnamed_" . $param. "}";
  1493.         $parameterdescs{$param} = "anonymous\n";
  1494.         $anon = 1;
  1495.     }
  1496.  
  1497.     # warn if parameter has no description
  1498.     # (but ignore ones starting with # as these are not parameters
  1499.     # but inline preprocessor statements);
  1500.     # also ignore unnamed structs/unions;
  1501.     if (!$anon) {
  1502.     if (!defined $parameterdescs{$param_name} && $param_name !~ /^#/) {
  1503.  
  1504.         $parameterdescs{$param_name} = $undescribed;
  1505.  
  1506.         if (($type eq 'function') || ($type eq 'enum')) {
  1507.             print STDERR "Warning(${file}:$.): Function parameter ".
  1508.             "or member '$param' not " .
  1509.             "described in '$declaration_name'\n";
  1510.         }
  1511.         print STDERR "Warning(${file}:$.):".
  1512.                      " No description found for parameter '$param'\n";
  1513.         ++$warnings;
  1514.         }
  1515.         }
  1516.  
  1517.     push @parameterlist, $param;
  1518.     $parametertypes{$param} = $type;
  1519. }
  1520.  
  1521. ##
  1522. # takes a function prototype and the name of the current file being
  1523. # processed and spits out all the details stored in the global
  1524. # arrays/hashes.
  1525. sub dump_function($$) {
  1526.     my $prototype = shift;
  1527.     my $file = shift;
  1528.  
  1529.     $prototype =~ s/^static +//;
  1530.     $prototype =~ s/^extern +//;
  1531.     $prototype =~ s/^fastcall +//;
  1532.     $prototype =~ s/^asmlinkage +//;
  1533.     $prototype =~ s/^inline +//;
  1534.     $prototype =~ s/^__inline__ +//;
  1535.     $prototype =~ s/^__inline +//;
  1536.     $prototype =~ s/^__always_inline +//;
  1537.     $prototype =~ s/^noinline +//;
  1538.     $prototype =~ s/__devinit +//;
  1539.     $prototype =~ s/^#define +//; #ak added
  1540.     $prototype =~ s/__attribute__ \(\([a-z,]*\)\)//;
  1541.  
  1542.     # Yes, this truly is vile.  We are looking for:
  1543.     # 1. Return type (may be nothing if we're looking at a macro)
  1544.     # 2. Function name
  1545.     # 3. Function parameters.
  1546.     #
  1547.     # All the while we have to watch out for function pointer parameters
  1548.     # (which IIRC is what the two sections are for), C types (these
  1549.     # regexps don't even start to express all the possibilities), and
  1550.     # so on.
  1551.     #
  1552.     # If you mess with these regexps, it's a good idea to check that
  1553.     # the following functions' documentation still comes out right:
  1554.     # - parport_register_device (function pointer parameters)
  1555.     # - atomic_set (macro)
  1556.     # - pci_match_device, __copy_to_user (long return type)
  1557.  
  1558.     if ($prototype =~ m/^()([a-zA-Z0-9_~:]+)\s*\(([^\(]*)\)/ ||
  1559.     $prototype =~ m/^(\w+)\s+([a-zA-Z0-9_~:]+)\s*\(([^\(]*)\)/ ||
  1560.     $prototype =~ m/^(\w+\s*\*)\s*([a-zA-Z0-9_~:]+)\s*\(([^\(]*)\)/ ||
  1561.     $prototype =~ m/^(\w+\s+\w+)\s+([a-zA-Z0-9_~:]+)\s*\(([^\(]*)\)/ ||
  1562.     $prototype =~ m/^(\w+\s+\w+\s*\*)\s*([a-zA-Z0-9_~:]+)\s*\(([^\(]*)\)/ ||
  1563.     $prototype =~ m/^(\w+\s+\w+\s+\w+)\s+([a-zA-Z0-9_~:]+)\s*\(([^\(]*)\)/ ||
  1564.     $prototype =~ m/^(\w+\s+\w+\s+\w+\s*\*)\s*([a-zA-Z0-9_~:]+)\s*\(([^\(]*)\)/ ||
  1565.     $prototype =~ m/^()([a-zA-Z0-9_~:]+)\s*\(([^\{]*)\)/ ||
  1566.     $prototype =~ m/^(\w+)\s+([a-zA-Z0-9_~:]+)\s*\(([^\{]*)\)/ ||
  1567.     $prototype =~ m/^(\w+\s*\*)\s*([a-zA-Z0-9_~:]+)\s*\(([^\{]*)\)/ ||
  1568.     $prototype =~ m/^(\w+\s+\w+)\s+([a-zA-Z0-9_~:]+)\s*\(([^\{]*)\)/ ||
  1569.     $prototype =~ m/^(\w+\s+\w+\s*\*)\s*([a-zA-Z0-9_~:]+)\s*\(([^\{]*)\)/ ||
  1570.     $prototype =~ m/^(\w+\s+\w+\s+\w+)\s+([a-zA-Z0-9_~:]+)\s*\(([^\{]*)\)/ ||
  1571.     $prototype =~ m/^(\w+\s+\w+\s+\w+\s*\*)\s*([a-zA-Z0-9_~:]+)\s*\(([^\{]*)\)/ ||
  1572.     $prototype =~ m/^(\w+\s+\w+\s+\w+\s+\w+)\s+([a-zA-Z0-9_~:]+)\s*\(([^\{]*)\)/ ||
  1573.     $prototype =~ m/^(\w+\s+\w+\s+\w+\s+\w+\s*\*)\s*([a-zA-Z0-9_~:]+)\s*\(([^\{]*)\)/)  {
  1574.     $return_type = $1;
  1575.     $declaration_name = $2;
  1576.     my $args = $3;
  1577.  
  1578.     create_parameterlist($args, ',', $file);
  1579.     } else {
  1580.     print STDERR "Error(${file}:$.): cannot understand prototype: '$prototype'\n";
  1581.     ++$errors;
  1582.     return;
  1583.     }
  1584.  
  1585.     output_declaration($declaration_name,
  1586.                'function',
  1587.                {'function' => $declaration_name,
  1588.             'module' => $modulename,
  1589.             'functiontype' => $return_type,
  1590.             'parameterlist' => \@parameterlist,
  1591.             'parameterdescs' => \%parameterdescs,
  1592.             'parametertypes' => \%parametertypes,
  1593.             'sectionlist' => \@sectionlist,
  1594.             'sections' => \%sections,
  1595.             'purpose' => $declaration_purpose
  1596.                });
  1597. }
  1598.  
  1599. sub process_file($);
  1600.  
  1601. # Read the file that maps relative names to absolute names for
  1602. # separate source and object directories and for shadow trees.
  1603. if (open(SOURCE_MAP, "<.tmp_filelist.txt")) {
  1604.     my ($relname, $absname);
  1605.     while(<SOURCE_MAP>) {
  1606.         chop();
  1607.         ($relname, $absname) = (split())[0..1];
  1608.         $relname =~ s:^/+::;
  1609.         $source_map{$relname} = $absname;
  1610.     }
  1611.     close(SOURCE_MAP);
  1612. }
  1613.  
  1614. if ($filelist) {
  1615.     open(FLIST,"<$filelist") or die "Can't open file list $filelist";
  1616.     while(<FLIST>) {
  1617.         chop;
  1618.         process_file($_);
  1619.     }
  1620. }
  1621.  
  1622. foreach (@ARGV) {
  1623.     chomp;
  1624.     process_file($_);
  1625. }
  1626. if ($verbose && $errors) {
  1627.   print STDERR "$errors errors\n";
  1628. }
  1629. if ($verbose && $warnings) {
  1630.   print STDERR "$warnings warnings\n";
  1631. }
  1632.  
  1633. exit($errors);
  1634.  
  1635. sub reset_state {
  1636.     $function = "";
  1637.     %constants = ();
  1638.     %parameterdescs = ();
  1639.     %parametertypes = ();
  1640.     @parameterlist = ();
  1641.     %sections = ();
  1642.     @sectionlist = ();
  1643.     $prototype = "";
  1644.  
  1645.     $state = 0;
  1646. }
  1647.  
  1648. sub process_state3_function($$) {
  1649.     my $x = shift;
  1650.     my $file = shift;
  1651.  
  1652.     if ($x =~ m#\s*/\*\s+MACDOC\s*#io || ($x =~ /^#/ && $x !~ /^#define/)) {
  1653.     # do nothing
  1654.     }
  1655.     elsif ($x =~ /([^\{]*)/) {
  1656.         $prototype .= $1;
  1657.     }
  1658.     if (($x =~ /\{/) || ($x =~ /\#define/) || ($x =~ /;/)) {
  1659.         $prototype =~ s@/\*.*?\*/@@gos;    # strip comments.
  1660.     $prototype =~ s@[\r\n]+@ @gos; # strip newlines/cr's.
  1661.     $prototype =~ s@^\s+@@gos; # strip leading spaces
  1662.     dump_function($prototype,$file);
  1663.     reset_state();
  1664.     }
  1665. }
  1666.  
  1667. sub process_state3_type($$) {
  1668.     my $x = shift;
  1669.     my $file = shift;
  1670.  
  1671.     $x =~ s@[\r\n]+@ @gos; # strip newlines/cr's.
  1672.     $x =~ s@^\s+@@gos; # strip leading spaces
  1673.     $x =~ s@\s+$@@gos; # strip trailing spaces
  1674.     if ($x =~ /^#/) {
  1675.     # To distinguish preprocessor directive from regular declaration later.
  1676.     $x .= ";";
  1677.     }
  1678.  
  1679.     while (1) {
  1680.         if ( $x =~ /([^{};]*)([{};])(.*)/ ) {
  1681.         $prototype .= $1 . $2;
  1682.         ($2 eq '{') && $brcount++;
  1683.         ($2 eq '}') && $brcount--;
  1684.         if (($2 eq ';') && ($brcount == 0)) {
  1685.             dump_declaration($prototype,$file);
  1686.         reset_state();
  1687.             last;
  1688.         }
  1689.         $x = $3;
  1690.         } else {
  1691.         $prototype .= $x;
  1692.         last;
  1693.     }
  1694.     }
  1695. }
  1696.  
  1697. # replace <, >, and &
  1698. sub xml_escape($) {
  1699.     my $text = shift;
  1700.     if (($output_mode eq "text") || ($output_mode eq "man")) {
  1701.         return $text;
  1702.     }
  1703.     $text =~ s/\&/\\\\\\amp;/g;
  1704.     $text =~ s/\</\\\\\\lt;/g;
  1705.     $text =~ s/\>/\\\\\\gt;/g;
  1706.     return $text;
  1707. }
  1708.  
  1709. sub process_file($) {
  1710.     my $file;
  1711.     my $identifier;
  1712.     my $func;
  1713.     my $initial_section_counter = $section_counter;
  1714.  
  1715.     if (defined($ENV{'SRCTREE'})) {
  1716.     $file = "$ENV{'SRCTREE'}" . "/" . "@_";
  1717.     }
  1718.     else {
  1719.     $file = "@_";
  1720.     }
  1721.     if (defined($source_map{$file})) {
  1722.     $file = $source_map{$file};
  1723.     }
  1724.  
  1725.     if (!open(IN,"<$file")) {
  1726.     print STDERR "Error: Cannot open file $file\n";
  1727.     ++$errors;
  1728.     return;
  1729.     }
  1730.  
  1731.     $section_counter = 0;
  1732.     while (<IN>) {
  1733.     if ($state == 0) {
  1734.         if (/$doc_start/o) {
  1735.         $state = 1;        # next line is always the function name
  1736.         $in_doc_sect = 0;
  1737.         }
  1738.     } elsif ($state == 1) {    # this line is the function name (always)
  1739.         if (/$doc_block/o) {
  1740.         $state = 4;
  1741.         $contents = "";
  1742.         if ( $1 eq "" ) {
  1743.             $section = $section_intro;
  1744.         } else {
  1745.             $section = $1;
  1746.         }
  1747.             }
  1748.         elsif (/$doc_decl/o) {
  1749.         $identifier = $1;
  1750.         if (/\s*([\w\s]+?)\s*-/) {
  1751.             $identifier = $1;
  1752.         }
  1753.  
  1754.         $state = 2;
  1755.         if (/-(.*)/) {
  1756.             $declaration_purpose = xml_escape($1);
  1757.         } else {
  1758.             $declaration_purpose = "";
  1759.         }
  1760.         if ($identifier =~ m/^struct/) {
  1761.             $decl_type = 'struct';
  1762.         } elsif ($identifier =~ m/^union/) {
  1763.             $decl_type = 'union';
  1764.         } elsif ($identifier =~ m/^enum/) {
  1765.             $decl_type = 'enum';
  1766.         } elsif ($identifier =~ m/^typedef/) {
  1767.             $decl_type = 'typedef';
  1768.         } else {
  1769.             $decl_type = 'function';
  1770.         }
  1771.  
  1772.         if ($verbose) {
  1773.             print STDERR "Info(${file}:$.): Scanning doc for $identifier\n";
  1774.         }
  1775.         } else {
  1776.         print STDERR "Warning(${file}:$.): Cannot understand $_ on line $.",
  1777.         " - I thought it was a doc line\n";
  1778.         ++$warnings;
  1779.         $state = 0;
  1780.         }
  1781.     } elsif ($state == 2) {    # look for head: lines, and include content
  1782.         if (/$doc_sect/o) {
  1783.         $newsection = $1;
  1784.         $newcontents = $2;
  1785.  
  1786.         if ($contents ne "") {
  1787.             if (!$in_doc_sect && $verbose) {
  1788.             print STDERR "Warning(${file}:$.): contents before sections\n";
  1789.             ++$warnings;
  1790.             }
  1791.             dump_section($section, xml_escape($contents));
  1792.             $section = $section_default;
  1793.         }
  1794.  
  1795.         $in_doc_sect = 1;
  1796.         $contents = $newcontents;
  1797.         if ($contents ne "") {
  1798.             while ((substr($contents, 0, 1) eq " ") ||
  1799.             substr($contents, 0, 1) eq "\t") {
  1800.                 $contents = substr($contents, 1);
  1801.             }
  1802.             $contents .= "\n";
  1803.         }
  1804.         $section = $newsection;
  1805.         } elsif (/$doc_end/) {
  1806.  
  1807.         if ($contents ne "") {
  1808.             dump_section($section, xml_escape($contents));
  1809.             $section = $section_default;
  1810.             $contents = "";
  1811.         }
  1812.  
  1813.         $prototype = "";
  1814.         $state = 3;
  1815.         $brcount = 0;
  1816. #        print STDERR "end of doc comment, looking for prototype\n";
  1817.         } elsif (/$doc_content/) {
  1818.         # miguel-style comment kludge, look for blank lines after
  1819.         # @parameter line to signify start of description
  1820.         if ($1 eq "" &&
  1821.             ($section =~ m/^@/ || $section eq $section_context)) {
  1822.             dump_section($section, xml_escape($contents));
  1823.             $section = $section_default;
  1824.             $contents = "";
  1825.         } else {
  1826.             $contents .= $1."\n";
  1827.         }
  1828.         } else {
  1829.         # i dont know - bad line?  ignore.
  1830.         print STDERR "Warning(${file}:$.): bad line: $_";
  1831.         ++$warnings;
  1832.         }
  1833.     } elsif ($state == 3) {    # scanning for function '{' (end of prototype)
  1834.         if ($decl_type eq 'function') {
  1835.             process_state3_function($_, $file);
  1836.         } else {
  1837.             process_state3_type($_, $file);
  1838.         }
  1839.     } elsif ($state == 4) {
  1840.         # Documentation block
  1841.             if (/$doc_block/) {
  1842.             dump_section($section, $contents);
  1843.             output_intro({'sectionlist' => \@sectionlist,
  1844.                       'sections' => \%sections });
  1845.             $contents = "";
  1846.             $function = "";
  1847.             %constants = ();
  1848.             %parameterdescs = ();
  1849.             %parametertypes = ();
  1850.             @parameterlist = ();
  1851.             %sections = ();
  1852.             @sectionlist = ();
  1853.             $prototype = "";
  1854.             if ( $1 eq "" ) {
  1855.                 $section = $section_intro;
  1856.             } else {
  1857.                 $section = $1;
  1858.             }
  1859.                 }
  1860.         elsif (/$doc_end/)
  1861.         {
  1862.             dump_section($section, $contents);
  1863.             output_intro({'sectionlist' => \@sectionlist,
  1864.                       'sections' => \%sections });
  1865.             $contents = "";
  1866.             $function = "";
  1867.             %constants = ();
  1868.             %parameterdescs = ();
  1869.             %parametertypes = ();
  1870.             @parameterlist = ();
  1871.             %sections = ();
  1872.             @sectionlist = ();
  1873.             $prototype = "";
  1874.             $state = 0;
  1875.         }
  1876.         elsif (/$doc_content/)
  1877.         {
  1878.             if ( $1 eq "" )
  1879.             {
  1880.                 $contents .= $blankline;
  1881.             }
  1882.             else
  1883.             {
  1884.                 $contents .= $1 . "\n";
  1885.             }
  1886.             }
  1887.           }
  1888.     }
  1889.     if ($initial_section_counter == $section_counter) {
  1890.     print STDERR "Warning(${file}): no structured comments found\n";
  1891.     if ($output_mode eq "xml") {
  1892.         # The template wants at least one RefEntry here; make one.
  1893.         print "<refentry>\n";
  1894.         print " <refnamediv>\n";
  1895.         print "  <refname>\n";
  1896.         print "   ${file}\n";
  1897.         print "  </refname>\n";
  1898.         print "  <refpurpose>\n";
  1899.         print "   Document generation inconsistency\n";
  1900.         print "  </refpurpose>\n";
  1901.         print " </refnamediv>\n";
  1902.         print " <refsect1>\n";
  1903.         print "  <title>\n";
  1904.         print "   Oops\n";
  1905.         print "  </title>\n";
  1906.         print "  <warning>\n";
  1907.         print "   <para>\n";
  1908.         print "    The template for this document tried to insert\n";
  1909.         print "    the structured comment from the file\n";
  1910.         print "    <filename>${file}</filename> at this point,\n";
  1911.         print "    but none was found.\n";
  1912.         print "    This dummy section is inserted to allow\n";
  1913.         print "    generation to continue.\n";
  1914.         print "   </para>\n";
  1915.         print "  </warning>\n";
  1916.         print " </refsect1>\n";
  1917.         print "</refentry>\n";
  1918.     }
  1919.     }
  1920. }
  1921.